'use strict';

const Service = require('egg').Service;
const sha1 = require('sha1') // sha1
const xml2js = require('xml2js');
const getRawBody = require('raw-body')
const ejs = require('ejs')
class WechatService extends Service {
  //微信校验签名
  async verification () {
    let { ctx, app } = this
    let token = app.config.wechatConfig.token
    let { nonce, echostr, timestamp, signature } = ctx.request.query
    let str = [token, nonce, timestamp].sort().join('')
    let vasignature = sha1(str)
    if (vasignature === signature) return echostr
    return false
  }
  //微信消息接收/回复
  async Message () {
    let { ctx } = this
    //接收xml数据
    let xml = await getRawBody(ctx.req, {
      length: ctx.request.length,
      limit: '1mb',
      encoding: ctx.request.charset || 'utf-8'
    })

    let result = await this.ParseXML(xml)
    let formatted = await this.FormatMessage(result.xml)
    if (formatted.MsgType === 'text') {
      return this.ToText(formatted)
    } else {
      return 'success'
    }
  }
  //解析xml
  async ParseXML (xml) {
    return new Promise((resolve, reject) => {
      xml2js.parseString(xml, { trim: true }, function (err, obj) {
        if (err) return reject(err)
        return resolve(obj)
      });
    });
  }
  //把数组转为对象
  async FormatMessage (result) {
    let message = {};
    if (typeof result === 'object') {
      for (let key in result) {
        if (!(result[key] instanceof Array) || result[key].length === 0) {
          continue;
        }
        if (result[key].length === 1) {
          let val = result[key][0];
          if (typeof val === 'object') {
            message[key] = formatMessage(val);
          } else {
            message[key] = (val || '').trim();
          }
        } else {
          message[key] = result[key].map(function (item) {
            return formatMessage(item);
          });
        }
      }
    }
    return message;
  }
  async messageTpl () {
    return '<xml>' +
      '<ToUserName><![CDATA[<%-toUserName%>]]></ToUserName>' +
      '<FromUserName><![CDATA[<%-fromUserName%>]]></FromUserName>' +
      '<CreateTime><%=createTime%></CreateTime>' +
      '<MsgType><![CDATA[<%=msgType%>]]></MsgType>' +
      '<Content><![CDATA[<%-content%>]]></Content>' +
      '</xml>';
  }
  async ToText (message) {
    let reply = {
      toUserName: message.FromUserName,
      fromUserName: message.ToUserName,
      createTime: new Date().getTime(),
      msgType: 'text',
      content: message.Content
    };
    let output = ejs.render(await this.messageTpl(), reply);
    return output;
  }


}

module.exports = WechatService
